package logic.trails;

import java.util.ArrayList;
import java.util.List;

import networking.messages.syncMessages.ValueType;

import logic.ships.moveableShip.MovableShip;
import logic.ships.moveableShip.NozzleSlot;
import logic.status.StatusChangedEvent;
import logic.status.StatusListener;

import com.jme.math.Vector3f;
import com.jme.scene.Spatial;
import com.jmex.effects.TrailMesh;

import factories.EffectFactory;

public class ShipTrail extends AbstractTrail {
	
	private static final long serialVersionUID = 1L;
	
	public static final int HIGH_QUAL_STEPS = 2;
	public static final int MED_QUAL_STEPS = 3;
	public static final int LOW_QUAL_STEPS = 4;
	
	public static final float DELAY_INC = 10f;
	
	private static final float SPEED_DIFF = 0.05f;
	
	private MovableShip ship;
	private NozzleSlot slot;
	
	public ShipTrail(float width, MovableShip ship, NozzleSlot slot) {
		super(ship, width, ship.getIngameState(), HIGH_QUAL_STEPS, MED_QUAL_STEPS, LOW_QUAL_STEPS, DELAY_INC);
		this.ship = ship;
		this.slot = slot;
		
		init();
		
		addSpeedListener();
		forceInvisibility(ship.getCurrentMovingSpeed() < SPEED_DIFF);
	}
	
	private void addSpeedListener() {
		StatusListener speedListener = new StatusListener() {
			@Override
			public void valueChanged(StatusChangedEvent event) {
				if(event.getType() == ValueType.Speed && ship.isVisibleToPlayer()) 
					forceInvisibility(event.getFloatValue() < SPEED_DIFF);
				else if(event.getType() == ValueType.HP && ship.isDestroyed()) 
					setVisible(false);
			}
		};
		ship.addStatusListener(speedListener, SPEED_DIFF);
	}
	
	@Override
	protected List<TrailMesh> getHighTrailMeshes() {
		List<TrailMesh> trailMeshes = new ArrayList<TrailMesh>();
		
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.blue));
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.darkBlue));
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.yellow));
		
		return trailMeshes;
	}
	
	@Override
	protected List<TrailMesh> getMediumTrailMeshes() {
		List<TrailMesh> trailMeshes = new ArrayList<TrailMesh>();
		
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.blue));
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.yellow));
		
		return trailMeshes;
	}
	
	@Override
	protected List<? extends Spatial> getLowTrailMeshes() {
		List<TrailMesh> trailMeshes = new ArrayList<TrailMesh>();
		
		trailMeshes.add(EffectFactory.getNozzleTrail(EffectFactory.blue));
		
		return trailMeshes;
	}
	
	@Override
	public Vector3f getTrailFrontLoc() {
		float frontSpeed = ship.getFrontSpeed();
		
		Vector3f inner = slot.getInnerLocation().clone();
		Vector3f outer = slot.getOuterLocation().clone();
		ship.localToWorld(inner, inner);
		ship.localToWorld(outer, outer);
		Vector3f dir = inner.subtract(outer).normalize().mult(frontSpeed);
		inner.addLocal(dir);
		return inner;
	}
}